1   /*
2    * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.
8    *
9    * This code is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12   * version 2 for more details (a copy is included in the LICENSE file that
13   * accompanied this code).
14   *
15   * You should have received a copy of the GNU General Public License version
16   * 2 along with this work; if not, write to the Free Software Foundation,
17   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18   *
19   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20   * or visit www.oracle.com if you need additional information or have any
21   * questions.
22   */
23  
24  
25  /* @test
26     @bug 6803681
27     @summary Test IBM1364
28   */
29  
30  import java.util.Arrays;
31  import java.nio.*;
32  import java.nio.charset.*;
33  
34  public class TestIBM1364 {
35      private static String c2bNRStr = "\u00AD\u00B7\u2015\u223C\u2299\uFF5E";
36      private static byte[] c2bNRBytes = new byte[] {
37          (byte)0x0e,
38          (byte)0x41, (byte)0x48,
39          (byte)0x41, (byte)0x43,
40          (byte)0x41, (byte)0x49,
41          (byte)0x42, (byte)0xa1,
42          (byte)0x49, (byte)0x6f,
43          (byte)0x49, (byte)0x54,
44          (byte)0x0f };
45  
46      // end at SO
47      private static String mixedStr = "\u008d\u008e\u0020\u3000\u3001\u71ba\u3164\u0088\ue757";
48      private static byte[] mixedBytes = new byte[] {
49           (byte)0x09,
50           (byte)0x0a,
51           (byte)0x40,
52           (byte)0x0e,
53           (byte)0x40, (byte)0x40,
54           (byte)0x41, (byte)0x41,
55           (byte)0x6c, (byte)0x45,
56           (byte)0x84, (byte)0x41,
57           (byte)0x0f,
58           (byte)0x28,
59           (byte)0x0e,
60           (byte)0xdd, (byte)0xfd,
61           (byte)0x0f };
62  
63      // end at SI
64      private static String mixedStr2 = "\u008d\u008e\u0020\u3000\u3001\u71ba\u3164\u0088";
65      private static byte[] mixedBytes2 = new byte[] {
66           (byte)0x09,
67           (byte)0x0a,
68           (byte)0x40,
69           (byte)0x0e,
70           (byte)0x40, (byte)0x40,
71           (byte)0x41, (byte)0x41,
72           (byte)0x6c, (byte)0x45,
73           (byte)0x84, (byte)0x41,
74           (byte)0x0f,
75           (byte)0x28 };
76  
77      private static byte[][] malformedBytes = {
78          { (byte)0x0e,
79            (byte)0x039, (byte)0x40,
80            (byte)0x0f
81          },
82          { (byte)0x0e,
83            (byte)0x039, (byte)0x42,
84            (byte)0x0f
85          },
86          { (byte)0x0e,
87            (byte)0x040, (byte)0x41,
88            (byte)0x0f
89          },
90          { (byte)0x0e,
91            (byte)0x040, (byte)0xee,
92            (byte)0x0f
93          },
94          { (byte)0x0e,
95            (byte)0x0ef, (byte)0x30,
96            (byte)0x0f
97          },
98          { (byte)0x0e,
99            (byte)0x0ff, (byte)0x41,
100           (byte)0x0f
101         }
102     };
103 
104     private static byte[][] unmappedBytes = {
105         { (byte)0x0e,
106           (byte)0x06c, (byte)0x46,
107           (byte)0x0f,
108         },
109         { (byte)0x0e,
110           (byte)0x078, (byte)0x46,
111           (byte)0x0f,
112         },
113         { (byte)0x0e,
114           (byte)0x083, (byte)0xfe,
115           (byte)0x0f,
116         },
117         { (byte)0xfa },
118         { (byte)0xfe },
119     };
120 
121     public static void main(String[] args) throws Exception {
122         if (!(Arrays.equals(mixedStr.getBytes("cp1364"), mixedBytes)) ||
123             !mixedStr.equals(new String(mixedBytes, "cp1364")))
124             throw new RuntimeException("cp1364 failed on mixed!");
125 
126         if (!(Arrays.equals(mixedStr2.getBytes("cp1364"), mixedBytes2)) ||
127             !mixedStr2.equals(new String(mixedBytes2, "cp1364")))
128             throw new RuntimeException("cp1364 failed on mixed!");
129 
130         if (!(Arrays.equals(c2bNRStr.getBytes("cp1364"), c2bNRBytes)) ||
131             c2bNRStr.equals(new String(c2bNRBytes, "cp1364")))
132             throw new RuntimeException("cp1364 failed on c2bNR!");
133 
134         ByteBuffer bb = ByteBuffer.allocateDirect(mixedBytes.length);
135         bb.put(mixedBytes).flip();
136         CharBuffer cb = Charset.forName("ibm1364").decode(bb);
137         if (!mixedStr.equals(new String(cb.toString())))
138             throw new RuntimeException("cp1364 failed on direct decod()!");
139 
140         bb = ByteBuffer.allocateDirect(mixedBytes2.length);
141         bb.put(mixedBytes2).flip();
142         cb = Charset.forName("ibm1364").decode(bb);
143         if (!mixedStr2.equals(new String(cb.toString())))
144             throw new RuntimeException("cp1364 failed on direct decod()!");
145 
146         cb = ByteBuffer.allocateDirect(mixedStr.length() * 2).asCharBuffer();
147         cb.put(mixedStr.toCharArray()).flip();
148         bb = Charset.forName("x-ibm1364").encode(cb);
149         if (!(Arrays.equals(Arrays.copyOf(bb.array(), bb.limit()), mixedBytes)))
150             throw new RuntimeException("cp1364 failed on direct encode()!");
151 
152         cb = ByteBuffer.allocateDirect(mixedStr2.length() * 2).asCharBuffer();
153         cb.put(mixedStr2.toCharArray()).flip();
154         bb = Charset.forName("x-ibm1364").encode(cb);
155         if (!(Arrays.equals(Arrays.copyOf(bb.array(), bb.limit()), mixedBytes2)))
156             throw new RuntimeException("cp1364 failed on direct encode()!");
157 
158         // malformed
159         cb = CharBuffer.allocate(1024);
160         CharBuffer cbd = ByteBuffer.allocateDirect(1024).asCharBuffer();
161         CharsetDecoder dec = Charset.forName("x-ibm1364").newDecoder();
162         for (byte[] ba:malformedBytes) {
163             cb.clear();
164             dec.reset();
165             if (!dec.reset().decode(ByteBuffer.wrap(ba), cb, true).isMalformed() ||
166                 !dec.reset().decode(ByteBuffer.wrap(ba), cbd, true).isMalformed())
167                 throw new RuntimeException("cp1364 failed on decode()/malformed!");
168         }
169 
170         //unmappable
171         for (byte[] ba:unmappedBytes) {
172             cb.clear();
173             dec.reset();
174             if (!dec.reset().decode(ByteBuffer.wrap(ba), cb, true).isUnmappable() ||
175                 !dec.reset().decode(ByteBuffer.wrap(ba), cbd, true).isUnmappable())
176                 throw new RuntimeException("cp1364 failed on decode()/unmappable!");
177         }
178 
179         //overflow
180         cb.limit(mixedStr.length() - 1);
181         cbd.limit(mixedStr.length() - 1);
182         if (!dec.reset().decode(ByteBuffer.wrap(mixedBytes), cb, true).isOverflow() ||
183             !dec.reset().decode(ByteBuffer.wrap(mixedBytes), cbd, true).isOverflow())
184             throw new RuntimeException("cp1364 failed on decode()/overflow!");
185 
186         CharsetEncoder enc = Charset.forName("x-ibm1364").newEncoder();
187         // last "0x0f" is from flush()
188         bb = ByteBuffer.allocate(mixedBytes.length - 2);
189         ByteBuffer bbd = ByteBuffer.allocateDirect(mixedBytes.length - 2);
190         if (!enc.reset()
191                 .encode(CharBuffer.wrap(mixedStr.toCharArray()), bb, true)
192                 .isOverflow() ||
193             !enc.reset()
194                 .encode(CharBuffer.wrap(mixedStr.toCharArray()), bbd, true)
195                 .isOverflow())
196             throw new RuntimeException("cp1364 failed on encode()/overflow!");
197 
198         // flush() overflow
199         bb = ByteBuffer.allocate(mixedBytes.length - 1);
200         bbd = ByteBuffer.allocateDirect(mixedBytes.length - 1);
201 
202         enc.reset().encode(CharBuffer.wrap(mixedStr.toCharArray()), bb, true);
203         enc.reset().encode(CharBuffer.wrap(mixedStr.toCharArray()), bbd, true);
204 
205         if (!enc.flush(bb).isOverflow() ||
206             !enc.flush(bbd).isOverflow())
207             throw new RuntimeException("cp1364 failed on encode()/flush()/overflow!");
208     }
209 }